package cn.com.infcn.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 搜索服务
 */
public abstract class MssServiceI {



	/***
	 * 
	 * 获取全部的分面,最大返回100条
	 *
	 * @param tableNames
	 * @param filter
	 * @param fields
	 * @return JSONArray
	 */
	public JSONArray getFenleiForOne(String tableNames, String filter, String fields) {
		return getFenleiForOne(tableNames, "100000", 100000, "", filter, fields);
	}

	/**
	 * 
	 * 描述: 获取一级分类
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param featchSize
	 * 
	 * @param size
	 *            int 获取分面的个数
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分 *
	 * @param fields
	 * @return JSONArray
	 */
	public abstract JSONArray getFenleiForOne(String tableNames, String featchSize, int size, String query, String filter,
			String fields);

	/**
	 * 获取两级分类
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分 *
	 * @param featchSize
	 * 
	 * @param size
	 *            int 获取分面的个数
	 * @param fields
	 * @return JSONArray
	 */
	public abstract JSONArray getFenleiForTwo(String tableNames, String featchSize, int size, String query, String filter,
			String fields);

	/**
	 * 
	 * 描述: 获取搜索的一条数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param defaultOperator
	 *            String 默认的运算符(默认or): and|or
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param heighlight
	 *            String 高亮
	 *            [{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]},{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]}]
	 * @param includes
	 *            String 返回结果包含哪些
	 * @param excludes
	 *            String 返回结果不包含哪些
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONObject
	 */
	public abstract JSONObject findOne(String tableNames, String defaultOperator, String query, String filter, String heighlight,
			String includes, String excludes, String sort) ;

	/**
	 * 
	 * 描述: 获取搜索数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param pageNum
	 *            int 起始位置
	 * @param size
	 *            int 返回结果数
	 * @param defaultOperator
	 *            String 默认的运算符(默认or): and|or
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param heighlight
	 *            String 高亮
	 *            [{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]},{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]}]
	 * @param includes
	 *            String 返回结果包含哪些
	 * @param excludes
	 *            String 返回结果不包含哪些
	 * @param distinct
	 *            String 去重
	 *            {"fetchCount":100,"fields":[{"field":"language","type":"hash"}],"mergeList":true}
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONObject
	 */
	public abstract JSONObject findList(String tableNames, int pageNum, int size, String defaultOperator, String query,
			String filter, String heighlight, String includes, String excludes, String distinct, String sort) ;

	/**
	 * 
	 * 描述: 获取搜索数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param heighlight
	 *            String 高亮
	 *            [{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]},{keyword:['体育'],query:'体育',begin:'<begin>',end:'<end>',fields:[{field:'content',dist_field:'content_hl',size:0}]}]
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @param pageNum
	 *            int 起始位置
	 * @param size
	 *            int 返回结果数
	 * @return JSONObject
	 */
	public JSONObject findList(String tableNames, String query, String filter, String heighlight, String sort,
			int pageNum, int size) {

		return findList(tableNames, pageNum, size, "OR", query, filter, heighlight, "", "", "", sort);
	}

	/**
	 * 
	 * 描述: 获取搜索数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @param pageNum
	 *            int 起始位置
	 * @param size
	 *            int 返回结果数
	 * @return JSONObject
	 */
	public JSONObject findList(String tableNames, String query, String filter, String sort, int pageNum, int size) {

		return findList(tableNames, query, filter, "", sort, pageNum, size);
	}

	/**
	 * 
	 * 描述: 获取搜索数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @param pageNum
	 *            int 起始位置
	 * @param size
	 *            int 返回结果数
	 * @return JSONObject
	 */
	public JSONObject findList(String tableNames, String query, String sort, int pageNum, int size) {

		return findList(tableNames, query, "", sort, pageNum, size);
	}

	/**
	 * 
	 * 描述: 获取搜索数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param pageNum
	 *            int 起始位置
	 * @param size
	 *            int 返回结果数
	 * @return JSONObject
	 */
	public JSONObject findList(String tableNames, String query, int pageNum, int size) {

		return findList(tableNames, query, "", pageNum, size);
	}

	/**
	 * 
	 * 描述: 获取搜索的所有的数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONArray
	 */

	public abstract JSONArray findAll(String tableNames, String query, String filter, String sort);

	/**
	 * 
	 * 描述: 获取搜索的所有的数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONArray
	 */

	public JSONArray findAll(String tableNames, String query, String sort) {
		return findAll(tableNames, query, "", sort);
	}

	/**
	 * 
	 * 描述: 获取搜索的所有的数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @return JSONArray
	 */

	public JSONArray findAll(String tableNames, String query) {
		return findAll(tableNames, query, "", "");
	}

	/**
	 * 
	 * 描述: 获取搜索的一条数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param filter
	 *            String 过滤语句不参与打分
	 * @param includes
	 *            String 返回结果包含哪些
	 * @param excludes
	 *            String 返回结果不包含哪些
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONObject
	 */
	public JSONObject findOne(String tableNames, String query, String filter, String includes, String excludes,
			String sort) {
		String defaultOperator = "OR";
		String heighlight = "";
		return findOne(tableNames, defaultOperator, query, filter, heighlight, includes, excludes, sort);
	}

	/**
	 * 
	 * 描述: 获取搜索的一条数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param includes
	 *            String 返回结果包含哪些
	 * @param excludes
	 *            String 返回结果不包含哪些
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONObject
	 */
	public JSONObject findOne(String tableNames, String query, String includes, String excludes, String sort) {

		String defaultOperator = "OR";
		String filter = "";
		String heighlight = "";
		return findOne(tableNames, defaultOperator, query, filter, heighlight, includes, excludes, sort);
	}

	/**
	 * 
	 * 描述: 获取搜索的一条数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @param sort
	 *            String 排序 sort pubyear|asc,_score|desc
	 * @return JSONObject
	 */
	public JSONObject findOne(String tableNames, String query, String sort) {
		String defaultOperator = "OR";
		String filter = "";
		String heighlight = "";
		String includes = "";
		String excludes = "";
		return findOne(tableNames, defaultOperator, query, filter, heighlight, includes, excludes, sort);
	}

	/**
	 * 
	 * 描述: 获取搜索的一条数据
	 *
	 * @param tableNames
	 *            String 多个表名按照,号分割table1,table2
	 * @param query
	 *            String 查询语句title:aa
	 * @return JSONObject
	 */
	public JSONObject findOne(String tableNames, String query) {
		String defaultOperator = "OR";
		String filter = "";
		String heighlight = "";
		String includes = "";
		String excludes = "";
		String sort = "";
		return findOne(tableNames, defaultOperator, query, filter, heighlight, includes, excludes, sort);
	}

	/**
	 * 
	 * 描述: 获取高亮的字符串(模糊高亮)
	 * 
	 * @param query:查询条件
	 * @param fileds:高亮的字段,如"title|10",高亮title,长度为10
	 * @return String
	 */
	public static String getHightLightStringByLike(String query, String... fileds) {
		return getHightLightString(false, true, new String[] {}, query, fileds);
	}

	/**
	 * 
	 * 描述: 获取高亮的字符串(精确高亮)
	 * 
	 * @param keyword:查询的关键词
	 * @param fileds:高亮的字段,如"title|10",高亮title,长度为10
	 * @return String
	 */
	public static String getHightLightStringByEqual(String[] keyword, String... fileds) {
		return getHightLightString(true, true, keyword, "", fileds);
	}

	/**
	 * 
	 * 描述: 获取高亮的字符串(模糊高亮)
	 * 
	 * @param isAddHLFlag:是否添加高亮标记,添加标记默认是"em"
	 * @param query:查询条件
	 * @param fileds:高亮的字段,如"title|10",高亮title,长度为10
	 * @return String
	 */
	public static String getHightLightStringByLike(boolean isAddHLFlag, String query, String... fileds) {
		return getHightLightString(false, isAddHLFlag, new String[] {}, query, fileds);
	}

	/**
	 * 
	 * 描述: 获取高亮的字符串(精确高亮)
	 * 
	 * @param isAddHLFlag:是否添加高亮标记,添加标记默认是"em"
	 * @param keyword:查询的关键词
	 * @param fileds:高亮的字段,如"title|10",高亮title,长度为10
	 * @return String
	 */
	public static String getHightLightStringByEqual(boolean isAddHLFlag, String[] keyword, String... fileds) {
		return getHightLightString(true, isAddHLFlag, keyword, "", fileds);
	}

	/**
	 * 描述: 获取高亮的字符串
	 * 
	 * @param isFullHightLight
	 *            是否是全匹配高亮
	 * @param isAddHLFlag
	 *            是否添加高亮标记,默认添加的标记是"em"
	 * @param keyword[]
	 *            高亮关键词数组
	 * @param query
	 *            模糊高亮的query
	 * @param fileds
	 *            高亮字段的配置：高亮的字段,如"title|10",高亮title,长度为10
	 * @return
	 */
	private static String getHightLightString(boolean isFullHightLight, boolean isAddHLFlag, String keyword[],
			String query, String... fileds) {

		JSONObject heighlightJSONObject = new JSONObject();
		JSONArray heighlightJSONArray = new JSONArray();
		if (isAddHLFlag) {
			heighlightJSONObject.put("begin", "<em class=\"search_hl\">");
			heighlightJSONObject.put("end", "</em>");
		} else {
			heighlightJSONObject.put("begin", "");
			heighlightJSONObject.put("end", "");
		}

		// 处理是否全匹配高亮
		if (isFullHightLight) {
			// query = "";// 因为是全匹配高亮,不用传query,是使用keyword参数
			heighlightJSONObject.put("keyword", keyword);
		} else {
			// keyword = "";// 因为不是全匹配高亮,不用传keyword,是使用query参数
			heighlightJSONObject.put("query", query);
		}

		heighlightJSONObject.put("single", false);
		heighlightJSONObject.put("fields", heighlightJSONArray);
		for (int i = 0; i < fileds.length; i++) {
			JSONObject tempJSONObject = new JSONObject();
			String[] split = fileds[i].split("\\|");
			tempJSONObject.put("dist_field", split[0] + "_HL");
			tempJSONObject.put("field", split[0]);
			tempJSONObject.put("size", split[1]);
			heighlightJSONArray.add(tempJSONObject);
		}

		return heighlightJSONObject.toJSONString();
	}

	/**
	 * 
	 * 描述: 特殊字符转译
	 *
	 * @param s
	 * @return String
	 */
	public static String escape(String s) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			// These characters are part of the query syntax and must be escaped
			if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^'
					|| c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || c == '?'
					|| c == '|' || c == '&' || c == '/') {
				sb.append('\\');
			}
			sb.append(c);
		}
		return sb.toString();
	}
}
